﻿#include <irrlicht.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#include <windows.h>
#include "resource.h"
#include "application.h"

#ifdef UNICODE
#define _stprintf wsprintf
#elif
#define _stprintf sprintf
#endif

#ifdef _MSC_VER
#ifdef _DEBUG
#pragma comment(lib,"libKernel_d.lib") 
#else
#pragma comment(lib,"libKernel.lib") 
#endif
//#pragma comment(linker,"/subsystem:windows /ENTRY:mainCRTStartup")
#endif
 
enum dir {
	UP			= 5,
	UP_LEFT		= 4,
	UP_RIGHT	= 6,
	DOWN		= 1,
	DOWN_LEFT	= 2,
	DOWN_RIGHT	= 0,
	LEFT		= 3,
	RIGHT		= 7
};

class AppEventReceiver : public IEventReceiver
{
public:
	AppEventReceiver()
	{
		for (u32 i = 0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
	}

	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
		}
		 
		return false;
	}

	virtual bool IsKeyDown(EKEY_CODE keyCode) const
	{
		return KeyIsDown[keyCode];
	}

	u32 KeyPressedCount()
	{
		u32 cnt = 0;
		for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i)
			if (KeyIsDown[i] == true) ++cnt;
		return cnt;
	}

private:
    bool KeyIsDown[KEY_KEY_CODES_COUNT];  
};

s32 AddAnimatedIconToSpriteBank(gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const array< io::path >& files, u32 frameTime)
{
	if (!spriteBank || !driver || !files.size())
		return -1;

	video::ITexture * tex = driver->getTexture(files[0]);
	if (tex)
	{
		array< rect<s32> >& spritePositions = spriteBank->getPositions();
		u32 idxRect = spritePositions.size();
		spritePositions.push_back(rect<s32>(0, 0, tex->getSize().Width, tex->getSize().Height));

		SGUISprite sprite;
		sprite.frameTime = frameTime;

		array< SGUISprite >& sprites = spriteBank->getSprites();
		u32 startIdx = spriteBank->getTextureCount();
		for (u32 f = 0; f < files.size(); ++f)
		{
			tex = driver->getTexture(files[f]);
			if (tex)
			{
				spriteBank->addTexture(driver->getTexture(files[f]));
				gui::SGUISpriteFrame frame;
				frame.rectNumber = idxRect;
				frame.textureNumber = startIdx + f;
				sprite.Frames.push_back(frame);
			}
		}

		sprites.push_back(sprite);
		return sprites.size() - 1;
	}

	return -1;
}
 
s32 AddAnimatedIconToSpriteBank(gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const array< rect<s32> >& rects, u32 frameTime)
{
	if (!spriteBank || !driver || !rects.size())
		return -1;

	video::ITexture * tex = driver->getTexture(file);
	if (tex)
	{
		array< rect<s32> >& spritePositions = spriteBank->getPositions();
		u32 idxRect = spritePositions.size();
		u32 idxTex = spriteBank->getTextureCount();
		spriteBank->addTexture(tex);

		SGUISprite sprite;
		sprite.frameTime = frameTime;

		array< SGUISprite >& sprites = spriteBank->getSprites();
		for (u32 i = 0; i < rects.size(); ++i)
		{
			spritePositions.push_back(rects[i]);

			gui::SGUISpriteFrame frame;
			frame.rectNumber = idxRect + i;
			frame.textureNumber = idxTex;
			sprite.Frames.push_back(frame);
		}

		sprites.push_back(sprite);
		return sprites.size() - 1;
	}

	return -1;
}
 
/*
Create a non-animated icon from the given file and position and put it into the spritebank.
We can use this icon later on in a cursor.
*/
s32 AddIconToSpriteBank(gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, const io::path& file, const core::rect<s32>& rect)
{
	if (!spriteBank || !driver)
		return -1;

	video::ITexture * tex = driver->getTexture(file);
	if (tex)
	{
		core::array< core::rect<irr::s32> >& spritePositions = spriteBank->getPositions();
		spritePositions.push_back(rect);
		array< SGUISprite >& sprites = spriteBank->getSprites();
		spriteBank->addTexture(tex);

		gui::SGUISpriteFrame frame;
		frame.rectNumber = spritePositions.size() - 1;
		frame.textureNumber = spriteBank->getTextureCount() - 1;

		SGUISprite sprite;
		sprite.frameTime = 0;
		sprite.Frames.push_back(frame);

		sprites.push_back(sprite);

		return sprites.size() - 1;
	}

	return -1;
}
 

int main(int argc, char** argv)  
{   

	Application *app = new Application(argc,argv); 
	app->run(); 

	// 
	//autoref<Sprite> sprite = new Sprite();

	//autoref<AppConfig> appconfig = new AppConfig();
	//appconfig->read();

	//AppEventReceiver receiver;
	//IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(1024, 600), 32U, false, false, false, &receiver);
	//
	//if (device == NULL) 
	//{
	//	return EXIT_FAILURE;
	//}

	//device->setWindowCaption(L"Tank Alpha");
	//device->setWindowStyle(true,false); 

	//IVideoDriver	*driver = device->getVideoDriver();
	//ISceneManager	*smgr	= device->getSceneManager();
	//IGUIEnvironment *env	= device->getGUIEnvironment();
	//IGUISkin		*skin	= env->getSkin();  

	//ITexture *tex = driver->getTexture(L"./media/tile_tree.png");
	//ITexture *tex_anim = driver->getTexture(L"./media/robot.png");
	//ITexture *tex_bg = driver->getTexture(L"./media/bg.jpg");
	//
	//TCHAR sysdir[512];
	//GetWindowsDirectory(sysdir, 512);

	//TCHAR fontdir[1024];
	//_stprintf(fontdir, L"%s\\Fonts\\msyh.ttf", sysdir);
	//CGUITTFont *font = CGUITTFont::createTTFont(device, fontdir, 40);
	//skin->setFont(font);
 //   
	//bool fadeOut = true;
	//int  lastFps = INT_MIN;

	//u32 then = device->getTimer()->getTime();

 //   const f32 fadeRateR = 0.01f;
	//const f32 fadeRateG = -0.02f;
	//const f32 fadeRateB = 0.02f;
	//const f32 fps = 60;
	//const u32 speed = 1;

	//f32 bg_r = 255.0f;
	//f32 bg_g = 255.0f;
	//f32 bg_b = 255.0f;

	//u32 sprite_x = 0;
	//u32 sprite_y = 0;
 //   
	//wchar_t str_fps[1024];
	//
	//driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
	//driver->getMaterial2D().AntiAliasing = video::EAAM_FULL_BASIC;
	//
	//IGUIImage* img; 
	//img = env->addImage(core::rect<s32>(0, 0, 25, 25));
	//img->setImage(tex);
	//img->setScaleImage(true);
	//driver->removeTexture(tex);

	//driver->makeColorKeyTexture(tex_anim, position2d<s32>(0, 0));

	//s32 currentFrame = 0;
	//dir row = dir::DOWN;
	//u32 lastKeyTime = 0; 
	//u32 frames = 0;

	//static u32 lastKeyCnt = 0;

	//bool validFrame = false;

	//HICON h_icon = ::LoadIcon(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_LOGO));
	////HICON hSmallIcon = (HICON)LoadImage(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_LOGO), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
	//HWND h_wnd = reinterpret_cast<HWND>(driver->getExposedVideoData().OpenGLWin32.HWnd);

	//HCURSOR h_cursor = ::LoadCursor(::GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_LOGO));
	//::SetCursor(h_cursor);

	//HINSTANCE h_instance = (HINSTANCE)GetModuleHandle(NULL);
	//HICON h_smallicon = (HICON)LoadImage(h_instance, MAKEINTRESOURCE(IDI_LOGO), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
	//HICON h_bigicon = (HICON)LoadImage(h_instance, MAKEINTRESOURCE(IDI_LOGO), IMAGE_ICON, 256, 256, LR_DEFAULTCOLOR);

	//SExposedVideoData exposedData = device->getVideoDriver()->getExposedVideoData();
	//HWND hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd);
	//
	//SendMessage(hWnd, WM_SETICON, ICON_SMALL, (long)h_smallicon);
	//SendMessage(hWnd, WM_SETICON, ICON_BIG, (long)h_bigicon);
	//
	//IGUISpriteBank *sprite_bank = env->addEmptySpriteBank(io::path("cursor_icons"));

	//array< io::path > files;
	//files.push_back(io::path("./media/cursor/icon_crosshairs16x16bw1.png"));
	//files.push_back(io::path("./media/cursor/icon_crosshairs16x16bw2.png"));
	//files.push_back(io::path("./media/cursor/icon_crosshairs16x16bw3.png"));
	//files.push_back(io::path("./media/cursor/icon_crosshairs16x16bw3.png"));
	//files.push_back(io::path("./media/cursor/icon_crosshairs16x16bw2.png"));
	//SCursorSprite spriteCursor;

	//spriteCursor.SpriteId = AddAnimatedIconToSpriteBank(sprite_bank, driver, files, 200);
	//spriteCursor.SpriteBank = sprite_bank;
	//spriteCursor.HotSpot = position2d<s32>(7, 7);

	//array< rect<s32> > iconRects;
	//iconRects.push_back(rect<s32>(0, 0, 16, 16));
	//iconRects.push_back(rect<s32>(16, 0, 32, 16));
	//iconRects.push_back(rect<s32>(0, 16, 16, 32));
	//iconRects.push_back(rect<s32>(0, 16, 16, 32));
	//iconRects.push_back(rect<s32>(16, 0, 32, 16));
	//SCursorSprite spriteCol;	// the sprite + some additional information needed for cursors
	//spriteCol.SpriteId = AddAnimatedIconToSpriteBank(sprite_bank, driver, io::path(L"./media/cursor/icon_crosshairs16x16col.png"), iconRects, 200);
	//spriteCol.HotSpot = position2d<s32>(7, 7);
	//spriteCol.SpriteBank = sprite_bank;

	//rect<s32> rectIcon;
	//SCursorSprite spriteNonAnimated(sprite_bank, 0, position2d<s32>(7, 7));
	//rectIcon = rect<s32>(0, 16, 16, 32); 
	//spriteNonAnimated.SpriteId = AddIconToSpriteBank(sprite_bank, driver, io::path(L"./media/cursor/icon_crosshairs16x16col.png"), rectIcon);

	//device->getCursorControl()->setVisible(true);   
	//device->getCursorControl()->addIcon(spriteCol); 
	//device->getCursorControl()->changeIcon((ECURSOR_ICON)spriteCol.SpriteId, spriteCol); 
	//device->getCursorControl()->setActiveIcon(ECURSOR_ICON(spriteCol.SpriteId));

	//while (device->run())
	//{  
	//	const u32 now = device->getTimer()->getTime();
	//	f32 delta = (f32)(now - then);
	//	f32 deltaKey = (f32)(now - lastKeyTime);
	//	 
	//	if (delta > 1000.0f / fps)
	//	{ 
	//		u32 keyCnt = receiver.KeyPressedCount(); 
	//		if (keyCnt != lastKeyCnt)
	//		{
	//			if (lastKeyCnt == 0 || deltaKey > 200)
	//			{
	//				lastKeyCnt = keyCnt;
	//				lastKeyTime = now;
	//			}
	//		}
	//		else if (keyCnt > 0)
	//		{
	//			if (receiver.IsKeyDown(KEY_UP))
	//			{
	//				sprite_y -= speed;
	//			}
	//			else if (receiver.IsKeyDown(KEY_DOWN))
	//			{
	//				sprite_y += speed;
	//			}
	//			if (receiver.IsKeyDown(KEY_LEFT))
	//			{
	//				sprite_x -= speed;
	//			}
	//			else if (receiver.IsKeyDown(KEY_RIGHT))
	//			{
	//				sprite_x += speed;
	//			}

	//			if (keyCnt == lastKeyCnt)
	//			{
	//				++currentFrame;
	//				if (receiver.IsKeyDown(KEY_UP))
	//				{
	//					if (receiver.IsKeyDown(KEY_LEFT))
	//						row = dir::UP_LEFT;
	//					else if (receiver.IsKeyDown(KEY_RIGHT))
	//						row = dir::UP_RIGHT;
	//					else
	//						row = dir::UP;
	//				}
	//				else if (receiver.IsKeyDown(KEY_DOWN))
	//				{
	//					if (receiver.IsKeyDown(KEY_LEFT))
	//						row = dir::DOWN_LEFT;
	//					else if (receiver.IsKeyDown(KEY_RIGHT))
	//						row = dir::DOWN_RIGHT;
	//					else
	//						row = dir::DOWN;
	//				}
	//				else if (receiver.IsKeyDown(KEY_LEFT))
	//				{
	//					if (receiver.IsKeyDown(KEY_UP))
	//						row = dir::UP_LEFT;
	//					else if (receiver.IsKeyDown(KEY_DOWN))
	//						row = dir::DOWN_LEFT;
	//					else
	//						row = dir::LEFT;
	//				}
	//				else if (receiver.IsKeyDown(KEY_RIGHT))
	//				{
	//					if (receiver.IsKeyDown(KEY_UP))
	//						row = dir::UP_RIGHT;
	//					else if (receiver.IsKeyDown(KEY_DOWN))
	//						row = dir::DOWN_RIGHT;
	//					else
	//						row = dir::RIGHT;
	//				}
	//			}
	//		}

	//		if (currentFrame >= 31)
	//			currentFrame = 0;

	//		then = now; 
	//	    
	//		u32 nFps = u32(frames*1000/delta);
	//		frames = 0;

	//		core::position2d<s32> m = device->getCursorControl()->getPosition();

	//		_stprintf(str_fps, L"fps:%d mouse: (x) %d (y) %d", driver->getFPS(), m.X, m.Y);

	//		if (m.X < 0 || m.Y < 0)
	//		{ 
	//			device->getCursorControl()->setActiveIcon(ECURSOR_ICON(ECI_NORMAL)); 
	//		}
	//		else
	//		{
	//			device->getCursorControl()->setActiveIcon(ECURSOR_ICON(spriteCol.SpriteId));
	//		}

	//		validFrame = true;
	//	}  

	//	if (device->isWindowActive())
	//	{
	//		driver->beginScene(true, true, SColor(255, (u32)bg_r, (u32)bg_g,(u32)bg_b));
	//		
	//		++frames;

	//	  /*driver->enableMaterial2D(); 
	//		driver->draw2DImage(tex, position2d<s32>(50, 50), rect<s32>(0, 0, 256, 100) , 0, SColor(255, 255, 255, 255), true);
	//		driver->enableMaterial2D(false);*/

	//	  /*env->addStaticText(L"Hello World!", rect<s32>(100, 20, 200, 30), true);*/

	//		sprite_bank->draw2DSprite(spriteCursor.SpriteId, position2di(580, 140), 0, video::SColor(255, 255, 255, 255), 0, device->getTimer()->getRealTime());
	//		
	//		driver->draw2DImage(tex_bg, position2d<s32>(0, 0),
	//			rect<s32>(0,0,1024,1024),
	//			0, SColor(255, 255, 255, 255), true);

	//		driver->draw2DImage(tex_anim,position2d<s32>(sprite_x,sprite_y),
	//			rect<s32>(currentFrame*64,row*64,(currentFrame+1)*64,(row+1)*64),
	//			0,SColor(255,255,255,255),true);
	//		
	//		skin->getFont()->draw(L"坦克 Alpha -- ©六月石娱乐®出品　日本の遊び", rect<s32>(133, 0, 0, 0), video::SColor(255, 255, 255, 255));
	//		if(validFrame)
	//			skin->getFont()->draw(str_fps, rect<s32>(133, 100, 0, 0), SColor(255, 255, 255, 255));

	//		driver->endScene();
	//	}

	return 0; 
  
} 